/*
 * Copyright the original author or authors.
 *
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.mozilla.org/MPL/MPL-1.1.html *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors:
 *   Russell Weir damonsbane/gmail dot com
 */
package hxbase.flash.media;
import hxbase.events.Event;
import hxbase.flash.events.EventTypes;
import hxbase.flash.IFlashWrapper;

class CameraEvents extends EventGroup {
	var onActivity	: Event<Bool->Void>;
	var onStatus : Event<Dynamic->Void>;

	override private function init() {
		onActivity = new Event<Bool->Void>(this);
		onStatus = new Event<Dynamic->Void>(this);
	}
}

class Camera extends hxbase.flash.events.EventDispatcher<CameraEvents>,
#if flash9
		implements IFlashWrapper<flash.media.Camera>
#else flash
		implements IFlashWrapper<flash.Camera>
#end
{
	public static var names(getNames, null) : Array<Dynamic>;
	public var activityLevel(getActivityLevel,null) : Float;
	public var bandwidth(getBandwidth,null) : Int;
	public var currentFps(getCurrentFps,null) : Float;
	public var fps(getFps,null) : Float;
	public var height(getHeight,null) : Int;
	public var index(getIndex,null) : Int;
	public var keyFrameInterval(getKeyFrameInterval,null) : Int;
	public var loopback(getLoopback,null) : Bool;
	public var motionLevel(getMotionLevel,null) : Float;	// AS2 is Int
	public var motionTimeout(getMotionTimeout,null) : Int;	// AS2 is Float
	public var muted(getMuted,null) : Bool;
	public var name(getName,null) : String;
	public var quality(getQuality,null) : Int;
	public var width(getWidth,null) : Int;

#if flash9
	var cam : flash.media.Camera;
#else flash
	var cam : flash.Camera;
#end

	private function new(?index : Int) {
		super();
		events = new CameraEvents();
#if flash9
		if(index != null)
			cam = flash.media.Camera.getCamera(Std.string(index));
		else
			cam = flash.media.Camera.getCamera();
#else flash
		cam = flash.Camera.get(index);
#end
	}

	public function getObject() {
		return cam;
	}




	////////////////////////////////////////////////////
	////		Wrapped statics			////
	////////////////////////////////////////////////////
	// as2 is array<String>
	public static function getNames() : Array<Dynamic> {
#if flash9
		return flash.media.Camera.names;
#else flash
		return flash.Camera.names;
#end
	}

	// As per note in Adobe live docs for AS3:
	//To specify a value for this parameter, use the string
	//representation of the zero-based index position within
	//the Camera.names array. For example, to specify the third
	//camera in the array, use Camera.getCamera("2").
	// So: NO we're not using strings here.. duh.
	public static function getCamera(?index : Int) : Camera {
		var c = new Camera(index);
		return c;
	}
	public static function get(?index : Int) {
		return getCamera(index);
	}

	////////////////////////////////////////////////////
	////		Wrapped methods			////
	////////////////////////////////////////////////////
	function setKeyFrameInterval(keyFrameInterval : Int) : Void {
		cam.setKeyFrameInterval(keyFrameInterval);
	}

	function setLoopback(?compress : Bool) : Void {
		if(compress == null)
			compress = false;
		cam.setLoopback(compress);
	}

	function setMode(width : Int, height : Int, ?fps : Float, ?favorArea : Bool) : Void {
		if(fps == null)
			fps = 15;
		if(favorArea == null)
			favorArea = true;
		cam.setMode(width,height,fps,favorArea);
	}

	function setMotionLevel(motionLevel : Int, ?timeOut : Int) : Void {
		cam.setMotionLevel(motionLevel, timeOut);
	}

	function setQuality(bandwidth : Int, ?quality : Int) : Void {
		if(quality == null)
			quality = 0;
		cam.setQuality(bandwidth, quality);
	}

	//f9 in haxe, not in adobe online docs
	//function setCursor(value : Bool) : Void // f9 only

	////////////////////////////////////////////////////
	////		Wrapped accessors		////
	////////////////////////////////////////////////////
	public function getActivityLevel() : Float {
		return cam.activityLevel;
	}
	public function getBandwidth() : Int {
		return cam.bandwidth;
	}
	public function getCurrentFps() : Float {
#if flash9
		return cam.currentFPS;
#else flash
		return cam.currentFps;
#end
	}
	public function getFps() : Float {
		return cam.fps;
	}
	public function getHeight() : Int {
		return cam.height;
	}
	public function getIndex() : Int {
		return cam.index;
	}
	public function getKeyFrameInterval() : Int {
		return cam.keyFrameInterval;
	}
	public function getLoopback() : Bool {
		return cam.loopback;
	}
	public function getMotionLevel() : Float {	// AS2 is Int
		return cam.motionLevel;
	}
	public function getMotionTimeout() : Int {	// AS2 is Float
#if flash9
		return cam.motionTimeout;
#else flash
		return cam.motionTimeOut;
#end
	}
	public function getMuted() : Bool {
		return cam.muted;
	}
	public function getName() : String {
		return cam.name;
	}
	public function getQuality() : Int {
		return cam.quality;
	}
	public function getWidth() : Int {
		return cam.width;
	}


	////////////////////////////////////////////////////
	////		Events				////
	////////////////////////////////////////////////////
	public function addEventListener(type :String, listener : Dynamic->Void) {
		switch(type) {
		case EventTypes.ACTIVITY:
			checkSubscribed(cam, type, onActivity);
			events.onActivity.bind(null, listener);
		case EventTypes.STATUS:
			checkSubscribed(cam, type, onStatus);
			events.onStatus.bind(null, listener);
		default:
			trace("["+here.methodName+"] Unknown event "+type);
		}
	}

	function onActivity(e) {
		events.onActivity.call(e);
	}

	function onStatus(e) {
		events.onStatus.call(e);
	}

//function onActivity(active : Bool) : Void
//function onStatus(infoObject : Dynacam) : Void
}
